#include "VEnginePCH.h"
#include "VRenderStateGLES.h"
int VRenderStateGLES::m_ActivatedTextureUnit = -1;
VTextureOGL* VRenderStateGLES::m_Texture[VR_MAX_TEXTURE_UNITS];
VTextureOGL* VRenderStateGLES::m_HWTexture[VR_MAX_TEXTURE_UNITS];
void VRenderStateGLES::CommitVertexFormat(EVRVertexFormat VertexFormat, EVRVertexFormat PreVertexFormat)
{
	switch(VertexFormat)
	{
	case VRVF_V3F:
		{
			glVertexPointer(3,GL_FLOAT,sizeof(VRVertexV3F), OGL_VBO_OFFSET(0));
			glDisableClientState(GL_NORMAL_ARRAY);
			glDisableClientState(GL_COLOR_ARRAY);
			for (int tu = 0; tu < VR_MAX_TEXTURE_UNITS; ++tu)
			{
				glClientActiveTexture(GL_TEXTURE0 + tu);
				glDisableClientState(GL_TEXTURE_COORD_ARRAY);
			}
		}
		break;
	case VRVF_V3FT2F:
		{
			glVertexPointer(3,GL_FLOAT,sizeof(VRVertexV3FT2F), OGL_VBO_OFFSET(0));
			glDisableClientState(GL_NORMAL_ARRAY);
			glDisableClientState(GL_COLOR_ARRAY);
			for (int tu = 1; tu < VR_MAX_TEXTURE_UNITS; ++tu)
			{
				glClientActiveTexture(GL_TEXTURE0 + tu);
				glDisableClientState(GL_TEXTURE_COORD_ARRAY);
			}
			glClientActiveTexture(GL_TEXTURE0);
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			glTexCoordPointer(2,GL_FLOAT,sizeof(VRVertexV3FT2F),OGL_VBO_OFFSET(VFIELD_OFFSET(VRVertexV3FT2F,u)));
		}
		break;
	case VRVF_V3FT2FT2F:
		{
			glVertexPointer(3,GL_FLOAT,sizeof(VRVertexV3FT2FT2F), OGL_VBO_OFFSET(0));
			glDisableClientState(GL_NORMAL_ARRAY);
			glDisableClientState(GL_COLOR_ARRAY);
			for (int tu = 2; tu < VR_MAX_TEXTURE_UNITS; ++tu)
			{
				glClientActiveTexture(GL_TEXTURE0 + tu);
				glDisableClientState(GL_TEXTURE_COORD_ARRAY);
			}
			glClientActiveTexture(GL_TEXTURE1);
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			glTexCoordPointer(2,GL_FLOAT,sizeof(VRVertexV3FT2FT2F),OGL_VBO_OFFSET(VFIELD_OFFSET(VRVertexV3FT2FT2F,u2)));

			glClientActiveTexture(GL_TEXTURE0);
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			glTexCoordPointer(2,GL_FLOAT,sizeof(VRVertexV3FT2FT2F),OGL_VBO_OFFSET(VFIELD_OFFSET(VRVertexV3FT2FT2F,u1)));
		}
		break;
	case VRVF_V3FC4UB:
		{
			glVertexPointer(3,GL_FLOAT,sizeof(VRVertexV3FC4UB), OGL_VBO_OFFSET(0));
			glDisableClientState(GL_NORMAL_ARRAY);
			glEnableClientState(GL_COLOR_ARRAY);
			glColorPointer(4,GL_UNSIGNED_BYTE,sizeof(VRVertexV3FC4UB),OGL_VBO_OFFSET(VFIELD_OFFSET(VRVertexV3FC4UB,diffuse)));
			for (int tu = 0; tu < VR_MAX_TEXTURE_UNITS; ++tu)
			{
				glClientActiveTexture(GL_TEXTURE0 + tu);
				glDisableClientState(GL_TEXTURE_COORD_ARRAY);
			}
		}
		break;
	case VRVF_V3FC4UBT2F:
		{
			glVertexPointer(3,GL_FLOAT,sizeof(VRVertexV3FC4UBT2F), OGL_VBO_OFFSET(0));
			glDisableClientState(GL_NORMAL_ARRAY);
			glEnableClientState(GL_COLOR_ARRAY);
			glColorPointer(4,GL_UNSIGNED_BYTE,sizeof(VRVertexV3FC4UBT2F),OGL_VBO_OFFSET(VFIELD_OFFSET(VRVertexV3FC4UBT2F,diffuse)));
			for (int tu = 1; tu < VR_MAX_TEXTURE_UNITS; ++tu)
			{
				glClientActiveTexture(GL_TEXTURE0 + tu);
				glDisableClientState(GL_TEXTURE_COORD_ARRAY);
			}
			glClientActiveTexture(GL_TEXTURE0);
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			glTexCoordPointer(2,GL_FLOAT,sizeof(VRVertexV3FC4UBT2F),OGL_VBO_OFFSET(VFIELD_OFFSET(VRVertexV3FC4UBT2F,u)));
		}
		break;
	case VRVF_V4FC4UBT2F:
		{
			glVertexPointer(4,GL_FLOAT,sizeof(VRVertexV4FC4UBT2F), OGL_VBO_OFFSET(0));
			glDisableClientState(GL_NORMAL_ARRAY);
			glEnableClientState(GL_COLOR_ARRAY);
			glColorPointer(4,GL_UNSIGNED_BYTE,sizeof(VRVertexV4FC4UBT2F),OGL_VBO_OFFSET(VFIELD_OFFSET(VRVertexV4FC4UBT2F,diffuse)));
			for (int tu = 1; tu < VR_MAX_TEXTURE_UNITS; ++tu)
			{
				glClientActiveTexture(GL_TEXTURE0 + tu);
				glDisableClientState(GL_TEXTURE_COORD_ARRAY);
			}
			glClientActiveTexture(GL_TEXTURE0);
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			glTexCoordPointer(2,GL_FLOAT,sizeof(VRVertexV4FC4UBT2F),OGL_VBO_OFFSET(VFIELD_OFFSET(VRVertexV4FC4UBT2F,u)));
		}
		break;
	case VRVF_V3FN3F:
		{
			glVertexPointer(4,GL_FLOAT,sizeof(VRVertexV3FN3F), OGL_VBO_OFFSET(0));
			glEnableClientState(GL_NORMAL_ARRAY);
			glNormalPointer(GL_FLOAT,sizeof(VRVertexV3FN3F),OGL_VBO_OFFSET(VFIELD_OFFSET(VRVertexV3FN3F,nx)));
			glDisableClientState(GL_COLOR_ARRAY);
			for (int tu = 0; tu < VR_MAX_TEXTURE_UNITS; ++tu)
			{
				glClientActiveTexture(GL_TEXTURE0 + tu);
				glDisableClientState(GL_TEXTURE_COORD_ARRAY);
			}
		}
		break;
	case VRVF_V3FN3FC4UB:
		{
			glVertexPointer(3,GL_FLOAT,sizeof(VRVertexV3FN3FC4UB), OGL_VBO_OFFSET(0));
			glEnableClientState(GL_NORMAL_ARRAY);
			glNormalPointer(GL_FLOAT,sizeof(VRVertexV3FN3FC4UB),OGL_VBO_OFFSET(VFIELD_OFFSET(VRVertexV3FN3FC4UB,nx)));
			glEnableClientState(GL_COLOR_ARRAY);
			glColorPointer(4,GL_UNSIGNED_BYTE,sizeof(VRVertexV3FN3FC4UB),OGL_VBO_OFFSET(VFIELD_OFFSET(VRVertexV3FN3FC4UB,diffuse)));
			for (int tu = 0; tu < VR_MAX_TEXTURE_UNITS; ++tu)
			{
				glClientActiveTexture(GL_TEXTURE0 + tu);
				glDisableClientState(GL_TEXTURE_COORD_ARRAY);
			}
		}
		break;
	case VRVF_V3FN3FT2F:
		{
			glEnableClientState(GL_VERTEX_ARRAY);
			glVertexPointer(3,GL_FLOAT,sizeof(VRVertexV3FN3FT2F), OGL_VBO_OFFSET(0));
			glEnableClientState(GL_NORMAL_ARRAY);
			glNormalPointer(GL_FLOAT,sizeof(VRVertexV3FN3FT2F),OGL_VBO_OFFSET(VFIELD_OFFSET(VRVertexV3FN3FT2F,nx)));
			glDisableClientState(GL_COLOR_ARRAY);
			for (int tu = 1; tu < VR_MAX_TEXTURE_UNITS; ++tu)
			{
				glClientActiveTexture(GL_TEXTURE0 + tu);
				glDisableClientState(GL_TEXTURE_COORD_ARRAY);
			}
			glClientActiveTexture(GL_TEXTURE0);
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			glTexCoordPointer(2,GL_FLOAT,sizeof(VRVertexV3FN3FT2F),OGL_VBO_OFFSET(VFIELD_OFFSET(VRVertexV3FN3FT2F,u)));
		}
		break;
	case VRVF_V3FN3FC4UBT2F:
		{
			glVertexPointer(3,GL_FLOAT,sizeof(VRVertexV3FN3FC4UBT2F), OGL_VBO_OFFSET(0));
			glEnableClientState(GL_NORMAL_ARRAY);
			glNormalPointer(GL_FLOAT,sizeof(VRVertexV3FN3FC4UBT2F),OGL_VBO_OFFSET(VFIELD_OFFSET(VRVertexV3FN3FC4UBT2F,nx)));
			glEnableClientState(GL_COLOR_ARRAY);
			glColorPointer(4,GL_UNSIGNED_BYTE,sizeof(VRVertexV3FN3FC4UBT2F),OGL_VBO_OFFSET(VFIELD_OFFSET(VRVertexV3FN3FC4UBT2F,diffuse)));
			for (int tu = 1; tu < VR_MAX_TEXTURE_UNITS; ++tu)
			{
				glClientActiveTexture(GL_TEXTURE0 + tu);
				glDisableClientState(GL_TEXTURE_COORD_ARRAY);
			}
			glClientActiveTexture(GL_TEXTURE0);
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			glTexCoordPointer(2,GL_FLOAT,sizeof(VRVertexV3FN3FC4UBT2F),OGL_VBO_OFFSET(VFIELD_OFFSET(VRVertexV3FN3FC4UBT2F,u)));
		}
		break;
	case VRVF_V3FC4UBT2FT2F:
		{
			glVertexPointer(3,GL_FLOAT,sizeof(VRVertexV3FC4UBT2FT2F), OGL_VBO_OFFSET(0));

			glDisableClientState(GL_NORMAL_ARRAY);

			glEnableClientState(GL_COLOR_ARRAY);
			glColorPointer(4,GL_UNSIGNED_BYTE,sizeof(VRVertexV3FC4UBT2FT2F),OGL_VBO_OFFSET(VFIELD_OFFSET(VRVertexV3FC4UBT2FT2F,diffuse)));
			for (int tu = 2; tu < VR_MAX_TEXTURE_UNITS; ++tu)
			{
				glClientActiveTexture(GL_TEXTURE0 + tu);
				glDisableClientState(GL_TEXTURE_COORD_ARRAY);
			}
			glClientActiveTexture(GL_TEXTURE1);
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			glTexCoordPointer(2,GL_FLOAT,sizeof(VRVertexV3FC4UBT2FT2F),OGL_VBO_OFFSET(VFIELD_OFFSET(VRVertexV3FC4UBT2FT2F,u2)));

			glClientActiveTexture(GL_TEXTURE0);
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			glTexCoordPointer(2,GL_FLOAT,sizeof(VRVertexV3FC4UBT2FT2F),OGL_VBO_OFFSET(VFIELD_OFFSET(VRVertexV3FC4UBT2FT2F,u1)));
		}
		break;
	case VRVF_V3FWATER:
		{
			if (PreVertexFormat != VRVF_V3FSHORE)
			{
				glVertexPointer(3,GL_FLOAT,sizeof(VRVertexV3FT2FT2F), OGL_VBO_OFFSET(0));
				glDisableClientState(GL_NORMAL_ARRAY);
				glDisableClientState(GL_COLOR_ARRAY);
				for (int tu = 3; tu < VR_MAX_TEXTURE_UNITS; ++tu)
				{
					glClientActiveTexture(GL_TEXTURE0 + tu);
					glDisableClientState(GL_TEXTURE_COORD_ARRAY);
				}
				glClientActiveTexture(GL_TEXTURE0);
				glEnableClientState(GL_TEXTURE_COORD_ARRAY);
				glTexCoordPointer(2,GL_FLOAT,sizeof(VRVertexV3FT2FT2F),OGL_VBO_OFFSET(VFIELD_OFFSET(VRVertexV3FT2FT2F,u1)));
			}
			glClientActiveTexture(GL_TEXTURE2);
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			glTexCoordPointer(2,GL_FLOAT,sizeof(VRVertexV3FT2FT2F),OGL_VBO_OFFSET(VFIELD_OFFSET(VRVertexV3FT2FT2F,u2)));

			glClientActiveTexture(GL_TEXTURE1);
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			glTexCoordPointer(2,GL_FLOAT,sizeof(VRVertexV3FT2FT2F),OGL_VBO_OFFSET(VFIELD_OFFSET(VRVertexV3FT2FT2F,u2)));

			break;
		}
	case VRVF_V3FSHORE:
		{
			glClientActiveTexture(GL_TEXTURE2);
			glDisableClientState(GL_TEXTURE_COORD_ARRAY);

			glClientActiveTexture(GL_TEXTURE1);
			glDisableClientState(GL_TEXTURE_COORD_ARRAY);

		}
	default:
		{
			// default state
			glDisableClientState(GL_NORMAL_ARRAY);
			for (int tu = 1; tu < VR_MAX_TEXTURE_UNITS; ++tu)
			{
				glClientActiveTexture(GL_TEXTURE0 + tu);
				glDisableClientState(GL_TEXTURE_COORD_ARRAY);
			}

			glEnableClientState(GL_VERTEX_ARRAY);
			glEnableClientState(GL_COLOR_ARRAY);
			glClientActiveTexture(GL_TEXTURE0);
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
		}
		break;
	}
}

void VRenderStateGLES::CommitVertexDeclaration(int Stream, VertexDeclarationOGL* VertexDecl)
{
	int StreamIndex;
	GLsizei StreamStride;
	for (INT e = 0; e < (int)VertexDecl->NumElement ; ++e)
	{
		VertexDeclarationOGL::Element& Compent = VertexDecl->Elements[e];
		StreamIndex = Compent.SteamIndex;
		if (StreamIndex != Stream)
		{
			continue;
		}
		StreamStride = (BYTE)VertexDecl->StreamSize[StreamIndex];
		if (Compent.Usage == VRVEU_POSITION)
		{
			glVertexPointer(Compent.Size,Compent.Type,StreamStride,OGL_VBO_OFFSET(Compent.Offset));	
			//// Ref@ http://www.nvidia.com/  GDC2003 <<Make better games.>>
		}
		else if (Compent.Usage == VRVEU_NORMAL)
		{
			glEnableClientState(GL_NORMAL_ARRAY);
			glNormalPointer(Compent.Type,StreamStride,OGL_VBO_OFFSET(Compent.Offset));
		}
		else if (Compent.Usage == VRVEU_DIFFUSE)
		{	
			glEnableClientState(GL_COLOR_ARRAY);
			glColorPointer(4,Compent.Type,StreamStride,OGL_VBO_OFFSET(Compent.Offset));
		}
		//else if (Compent.Usage == RSVBE_USAGE_SPECULAR)
		//{
		//	glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
		//	glSecondaryColorPointerEXT(/*Compent.wSize*/4,Compent.dwType,m_CurVertexDeclaration->szStreamSize[nStream],OGL_VBO_OFFSET(Compent.dwOffset));	
		//	m_dwCurArrayFlag |= OGL_VAEF_SPECULAR;
		//}
		else if (VRVEU_TEXCOORD0 <= Compent.Usage && Compent.Usage <= VRVEU_TEXCOORD7)
		{
			glClientActiveTexture(GL_TEXTURE0 + Compent.Usage - VRVEU_TEXCOORD0);
			glTexCoordPointer(Compent.Size,Compent.Type,StreamStride,OGL_VBO_OFFSET(Compent.Offset));
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
		}
		/*else if (Compent.Usage == RSVBE_USAGE_BLEND_INDICES)
		{
		glVertexAttribPointerARB(7, Compent.wSize,Compent.dwType,GL_FALSE,m_CurVertexDeclaration->szStreamSize[nStream],OGL_VBO_OFFSET(Compent.dwOffset));
		glEnableVertexAttribArrayARB(7);
		m_dwCurArrayFlag |= OGL_VAEF_BLEND_INDICES;
		}
		else if(Compent.Usage == RSVBE_USAGE_BLEND_WEIGHTS)
		{
		glVertexAttribPointerARB(1, Compent.wSize,Compent.dwType,GL_FALSE,m_CurVertexDeclaration->szStreamSize[nStream],OGL_VBO_OFFSET(Compent.dwOffset));
		glEnableVertexAttribArrayARB(1);
		m_dwCurArrayFlag |= OGL_VAEF_BLEND_WEIGHTS;
		}*/
	}
}